]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
scroll-view: Add proper smooth scrolling
authorJasper St. Pierre <jstpierre@mecheye.net>
Sun, 4 Nov 2012 15:10:50 +0000 (10:10 -0500)
committerJasper St. Pierre <jstpierre@mecheye.net>
Thu, 20 Dec 2012 13:40:04 +0000 (08:40 -0500)
The code here before was added as dummy code to satisfy an error
in the missing switch, and wasn't ever tested due to the lack of XI2
in mutter. Use the same math as GtkRange does to calculate scroll bar
positions from raw XI2 deltas to allow for proper smooth scrolling.

https://bugzilla.gnome.org/show_bug.cgi?id=687573

src/st/st-adjustment.c
src/st/st-adjustment.h
src/st/st-scroll-view.c

index e2ef9b2f3a54b5e7aeb512cba374749b7ddcbae0..e6b33670cd36a19e7a9beacd3e5a031525329c1a 100644 (file)
@@ -566,3 +566,31 @@ st_adjustment_get_values (StAdjustment *adjustment,
     *page_size = priv->page_size;
 }
 
+/**
+ * st_adjustment_adjust_for_scroll_event:
+ * @adjustment: An #StAdjustment
+ * @delta: A delta, retrieved directly from clutter_event_get_scroll_delta()
+ *   or similar.
+ *
+ * Adjusts the adjustment using delta values from a scroll event.
+ * You should use this instead of using st_adjustment_set_value()
+ * as this method will tweak the values directly using the same
+ * math as GTK+, to ensure that scrolling is consistent across
+ * the environment.
+ */
+void
+st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment,
+                                       gdouble       delta)
+{
+  StAdjustmentPrivate *priv;
+  gdouble new_value, scroll_unit;
+
+  g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
+
+  priv = adjustment->priv;
+
+  scroll_unit = pow (priv->page_size, 2.0 / 3.0);
+
+  new_value = priv->value + delta * scroll_unit;
+  st_adjustment_set_value (adjustment, new_value);
+}
index 7660a08ecad40e52d2e0311a529a47e127ce1408..fe041cf8ad73be4e902959be95b5eda9952ea6f4 100644 (file)
@@ -99,6 +99,10 @@ void          st_adjustment_get_values  (StAdjustment *adjustment,
                                          gdouble      *step_increment,
                                          gdouble      *page_increment,
                                          gdouble      *page_size);
+
+void          st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment,
+                                                     gdouble       delta);
+
 G_END_DECLS
 
 #endif /* __ST_ADJUSTMENT_H__ */
index c8f89ceee23d9608cd90fb63922be0b6073b23ce..285ba2d6049c0a77c1b5856b052bbec4d26d7b82 100644 (file)
@@ -665,6 +665,30 @@ st_scroll_view_allocate (ClutterActor          *actor,
 
 }
 
+static void
+adjust_with_direction (StAdjustment           *adj,
+                       ClutterScrollDirection  direction)
+{
+  gdouble delta;
+
+  switch (direction)
+    {
+    case CLUTTER_SCROLL_UP:
+    case CLUTTER_SCROLL_LEFT:
+      delta = -1.0;
+      break;
+    case CLUTTER_SCROLL_RIGHT:
+    case CLUTTER_SCROLL_DOWN:
+      delta = 1.0;
+      break;
+    case CLUTTER_SCROLL_SMOOTH:
+      g_assert_not_reached ();
+      break;
+    }
+
+  st_adjustment_adjust_for_scroll_event (adj, delta);
+}
+
 static void
 st_scroll_view_style_changed (StWidget *widget)
 {
@@ -687,57 +711,31 @@ st_scroll_view_scroll_event (ClutterActor       *self,
                              ClutterScrollEvent *event)
 {
   StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv;
-  gdouble value, step, hvalue, vvalue, delta_x, delta_y;
 
   /* don't handle scroll events if requested not to */
   if (!priv->mouse_scroll)
     return FALSE;
 
-  switch (event->direction)
-    {
-    case CLUTTER_SCROLL_SMOOTH:
-      clutter_event_get_scroll_delta ((ClutterEvent *)event,
-                                      &delta_x, &delta_y);
-      g_object_get (priv->hadjustment,
-                    "value", &hvalue,
-                    NULL);
-      g_object_get (priv->vadjustment,
-                    "value", &vvalue,
-                    NULL);
-      break;
-    case CLUTTER_SCROLL_UP:
-    case CLUTTER_SCROLL_DOWN:
-      g_object_get (priv->vadjustment,
-                    "step-increment", &step,
-                    "value", &value,
-                    NULL);
-      break;
-    case CLUTTER_SCROLL_LEFT:
-    case CLUTTER_SCROLL_RIGHT:
-      g_object_get (priv->hadjustment,
-                    "step-increment", &step,
-                    "value", &value,
-                    NULL);
-      break;
-    }
+  if (clutter_event_is_pointer_emulated ((ClutterEvent *) event))
+    return TRUE;
 
   switch (event->direction)
     {
     case CLUTTER_SCROLL_SMOOTH:
-      st_adjustment_set_value (priv->hadjustment, hvalue + delta_x);
-      st_adjustment_set_value (priv->vadjustment, vvalue + delta_y);
+      {
+        gdouble delta_x, delta_y;
+        clutter_event_get_scroll_delta ((ClutterEvent *)event, &delta_x, &delta_y);
+        st_adjustment_adjust_for_scroll_event (priv->hadjustment, delta_x);
+        st_adjustment_adjust_for_scroll_event (priv->vadjustment, delta_y);
+      }
       break;
     case CLUTTER_SCROLL_UP:
-      st_adjustment_set_value (priv->vadjustment, value - step);
-      break;
     case CLUTTER_SCROLL_DOWN:
-      st_adjustment_set_value (priv->vadjustment, value + step);
+      adjust_with_direction (priv->vadjustment, event->direction);
       break;
     case CLUTTER_SCROLL_LEFT:
-      st_adjustment_set_value (priv->hadjustment, value - step);
-      break;
     case CLUTTER_SCROLL_RIGHT:
-      st_adjustment_set_value (priv->hadjustment, value + step);
+      adjust_with_direction (priv->hadjustment, event->direction);
       break;
     }